home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / uip / other / sendmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-10-10  |  6.9 KB  |  345 lines

  1. /*
  2. **  A Sendmail fake.
  3. */
  4.  
  5. #include <signal.h>
  6. #include <pwd.h>
  7. #include "util.h"
  8. #include "mmdf.h"
  9. #include "cnvtdate.h"
  10.  
  11. extern    char    *locname;
  12. extern    char    *chndfldir;
  13.  
  14. extern struct passwd *getpwuid ();
  15. extern char *getmailid ();
  16. extern char *getenv();
  17. extern char *dupfpath();
  18. extern char *multcat();
  19. extern int exit();
  20.  
  21. char    *SMTPSRVR = "smtpsrvr";
  22.  
  23. char    *FullName;    /* sender's full name */
  24. char    *from;        /* sender's mail address */
  25. char    subflags[128];    /* flags for submit */
  26. int    watch;
  27. int    verify;
  28. int    extract;
  29. int    badaddrs;
  30. int    rewritefrom;
  31.  
  32. int    die();
  33.  
  34. /*ARGSUSED*/
  35. main(argc, argv)
  36. int argc;
  37. char **argv;
  38. {
  39.     struct passwd  *pwdptr;
  40.     register char *p;
  41.     register char **av;
  42.     struct rp_bufstruct thereply;
  43.     int    retval;
  44.     int     len;
  45.  
  46.     mmdf_init(argv[0]);
  47.  
  48.     if ((pwdptr = getpwuid (getuid())) == (struct passwd *) NULL)
  49.         syserr("Unable to locate user's name");
  50.  
  51.     if ((from = getmailid(pwdptr -> pw_name)) == NULL)
  52.         syserr("Unable to locate user's mailid");
  53.  
  54.     from = multcat(from, "@", locname, (char *)0);
  55.  
  56.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  57.         (void) signal(SIGINT, die);
  58.     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
  59.         (void) signal(SIGHUP, die);
  60.     (void) signal(SIGTERM, die);
  61.     (void) signal(SIGPIPE, die);
  62.  
  63.     FullName = getenv("NAME");
  64.  
  65.     av = argv;
  66.     while ((p = *++av) != NULL && p[0] == '-') {
  67.         switch (p[1]) {
  68.         case 'b':    /* operations mode */
  69.             switch (p[2]) {
  70.             case 'a':    /* smtp on stdin */
  71.             case 's':    /* smtp on stdin */
  72.                 smtp();
  73.                 exit(98);    /* should never happen */
  74.             case 'm':    /* just send mail */
  75.                 continue;
  76.             case 'v':    /* verify mode */
  77.                 verify++;
  78.                 continue;
  79.             default:
  80.                 syserr("Invalid operation mode %c", p[2]);
  81.             }
  82.             continue;
  83.  
  84.         case 'f':    /* from address */
  85.         case 'r':    /* obsolete -f flag */
  86.             p += 2;
  87.             if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
  88.             {
  89.                 p = *++av;
  90.                 if (p == NULL || *p == '-') {
  91.                     syserr("No \"from\" person");
  92.                     av--;
  93.                     continue;
  94.                 }
  95.             }
  96.             if (rewritefrom) {
  97.                 syserr("More than one \"from\" person");
  98.                 continue;
  99.             }
  100.             from = p;
  101.             rewritefrom++;
  102.             continue;
  103.  
  104.         case 'F':    /* set full name */
  105.             p += 2;
  106.             if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
  107.             {
  108.                 syserr("Bad -F flag");
  109.                 av--;
  110.                 continue;
  111.             }
  112.             FullName = p;
  113.             continue;
  114.  
  115.         case 'h':    /* hop count */
  116.             p += 2;
  117.             if (*p == '\0' && ((p = *++av) == NULL || !isdigit(*p)))
  118.             {
  119.                 syserr("Bad hop count (%s)", p);
  120.                 av--;
  121.                 continue;
  122.             }
  123.             continue;    /* Ignore */
  124.  
  125.         case 't':    /* read recipients from message */
  126.             extract++;
  127.             continue;
  128.  
  129.  
  130.         case 'v':    /* give blow-by-blow description */
  131.             watch++;
  132.             continue;
  133.  
  134.         case 'T':    /* set timeout interval */
  135.         case 'C':    /* select configuration file (already done) */
  136.         case 'c':    /* connect to non-local mailers */
  137.         case 'd':    /* debug */
  138.         case 'e':    /* error message disposition */
  139.         case 'i':    /* don't let dot stop me */
  140.         case 'm':    /* send to me too */
  141.         case 'n':    /* don't alias */
  142.         case 'o':    /* set option, handled in line */
  143.         case 's':    /* save From lines in headers */
  144.             continue;
  145.         }
  146.     }
  147.  
  148.     setuid(getuid());
  149.  
  150.     if (verify && extract)
  151.         syserr("Verify mode not supported on header components");
  152.  
  153.     strcpy(subflags, "ml");
  154.     if (rewritefrom)
  155.         strcat(subflags, "t");
  156.     if (watch)
  157.         strcat(subflags, "w");
  158.     if (!extract)
  159.         strcat(subflags, "v");
  160.     else
  161.         strcat(subflags, "xto,cc,bcc*");
  162.  
  163.     if (rp_isbad (mm_init ()) || rp_isbad (mm_sbinit ()))
  164.         syserr("Unable to submit mail at this time");
  165.     if (rp_isbad (mm_winit ((char *) 0, subflags, from)))
  166.         syserr("Problem with submit message initialization");
  167.     if (!extract) {
  168.         if (rp_isbad (retval = mm_rrply (&thereply, &len)))
  169.             syserr("Initialization reply failure");
  170.         switch (rp_gbval (thereply.rp_val)) {
  171.         case RP_BNO:
  172.         case RP_BTNO:
  173.             syserr("Initialization failure: %s", thereply.rp_line);
  174.         }
  175.     }
  176.  
  177.     if (*av == NULL && !extract) {
  178.         syserr("Usage: /usr/lib/sendmail [flags] addr...");
  179.     }
  180.     if (!extract) {
  181.         while (*av)
  182.             send_address(*av++);
  183.         if (rp_isbad (mm_waend ()))
  184.             syserr("Problem with address list.");
  185.     }
  186.     if (verify) {
  187.         mm_end(NOTOK);
  188.         exit(badaddrs ? 1 : 0);
  189.     }
  190.  
  191.     doheader();
  192.  
  193.     exit(dobody());
  194. }
  195.  
  196. send_address (addr)
  197. char    *addr;
  198. {
  199.     struct rp_bufstruct thereply;
  200.     int     retval;
  201.     int     len;
  202.  
  203.     if (watch) {
  204.         printf ("%s:  ", addr);
  205.         fflush (stdout);
  206.     }
  207.  
  208.     if (rp_isbad (retval = mm_wadr ((char *)0, addr)) ||
  209.         rp_isbad (retval = mm_rrply (&thereply, &len)))
  210.         syserr("Problem in send_address [%s].", rp_valstr (retval));
  211.     switch (rp_gval (thereply.rp_val)) {
  212.     case RP_AOK: 
  213.         if(watch) printf ("address ok\n");
  214.         break;
  215.  
  216.     case RP_NO: 
  217.         if(watch) printf ("not deliverable; unknown problem\n");
  218.         badaddrs = TRUE;
  219.         break;
  220.  
  221.     case RP_USER: 
  222.         if(watch) printf ("not deliverable; unknown address.\n");
  223.         badaddrs = TRUE;
  224.         break;
  225.  
  226.     case RP_NDEL: 
  227.         if(watch) printf ("not deliverable; permanent error.\n");
  228.         badaddrs = TRUE;
  229.         break;
  230.  
  231.     case RP_AGN: 
  232.         if(watch) printf ("failed, this attempt; try later\n");
  233.         badaddrs = TRUE;
  234.         break;
  235.  
  236.     case RP_NOOP: 
  237.         if(watch) printf ("not attempted, this time; perhaps try later.\n");
  238.         badaddrs = TRUE;
  239.         break;
  240.  
  241.     default: 
  242.         syserr("Unexpected address response:  %s", thereply.rp_line);
  243.     }
  244.     fflush (stdout);
  245. }
  246.  
  247. doheader()
  248. {
  249.     int    gotfrom, gotsender, gotdate;
  250.     char    line[LINESIZE];
  251.  
  252.     gotfrom = gotsender = gotdate = 0;
  253.     while (fgets (line, LINESIZE, stdin) != NULL) {
  254.         if (line[0] == '\n')
  255.             break;
  256.         if (prefix ("Date:", line))
  257.             gotdate++;
  258.         if (prefix ("From:", line)) {
  259.             gotfrom++;
  260.             if (rewritefrom) {
  261.                 dofrom();
  262.                 continue;
  263.             }
  264.         }
  265.         if (prefix ("Sender:", line))
  266.             gotsender++;
  267.         mm_wtxt (line, strlen (line));
  268.     }
  269.     if (!gotdate) {
  270.         strcpy (line, "Date: ");
  271.         cnvtdate (TIMREG, line+6);
  272.         strcat (line, "\n");
  273.         mm_wtxt (line, strlen(line));
  274.     }
  275.     if (!gotfrom)
  276.         dofrom();
  277.     if (!gotsender) {
  278.         sprintf(line, "Sender: %s\n", from);
  279.         mm_wtxt (line, strlen(line));
  280.     }
  281.     mm_wtxt("\n", 1);
  282. }
  283.  
  284. dofrom()
  285. {
  286.     char    line[128];
  287.  
  288.     if (isstr(FullName))
  289.         sprintf(line, "From: %s <%s>\n", FullName, from);
  290.     else
  291.         sprintf(line, "From: %s\n", from);
  292.     mm_wtxt(line, strlen(line));
  293. }
  294.  
  295. dobody()
  296. {
  297.     struct rp_bufstruct thereply;
  298.     char    buffer[BUFSIZ];
  299.     register int    i;
  300.     int     len;
  301.  
  302.     while (!feof (stdin) && !ferror (stdin) &&
  303.         (i = fread (buffer, sizeof (char), sizeof (buffer), stdin)) > 0)
  304.         if (rp_isbad (i = mm_wtxt (buffer, i)))
  305.             syserr("Problem writing body");
  306.  
  307.     if (ferror (stdin))
  308.         syserr("Problem reading body");
  309.  
  310.     if (rp_isbad (mm_wtend ()) || rp_isbad (mm_rrply (&thereply, &len)))
  311.         syserr("problem ending submission");
  312.  
  313.     if (rp_isbad (thereply.rp_val))
  314.         syserr("%s", thereply.rp_line);
  315.  
  316.     return(0);    /* eventually the program exit value */
  317. }
  318.  
  319. smtp()
  320. {
  321.     char    *smtpd = dupfpath(SMTPSRVR, chndfldir);
  322.  
  323.     setuid(geteuid());    /* Must become "mmdf" for real */
  324.     execl (smtpd, "sendmail-smtp", from, locname, "local", (char *)0);
  325.     perror(smtpd);
  326.     exit(9);
  327. }
  328.  
  329. /*VARARGS1*/
  330. syserr(fmt, a, b)
  331. char    *fmt, *a, *b;
  332. {
  333.     fprintf(stderr, fmt, a, b);
  334.     fputc('\n', stderr);
  335.     exit(9);
  336. }
  337.  
  338. die(sig)
  339. int sig;
  340. {
  341.     mm_end(NOTOK);
  342.     fprintf(stderr, "sendmail: dying from signal %d\n", sig);
  343.     exit(99);
  344. }
  345.